我們終於進入 Node.js 這個主題了,真是令人興奮
Node.js 近幾年有得到許多關注,對於一般人的認知他是一種後端「語言」或是「框架」
但是事實上,他這兩個都不算
Node.js 基本上就是,讓你可以在後端也寫 JavaScript 的一堆函式庫
如果有寫過一點 JavaScript 的話
對於 JavaScript 的印象應該是一種可以跑在「瀏覽器」這個特定環境的小語言(現在已經不小了)
其實在定位上,他早期比較接近 Lua (一種很適合寫各種遊戲插件的腳本語言)
現在問題來了
既然 JavaScript 也可以在後端執行?
那是不是 Python, Java, C 也可以寫前端呢?
想要知道這點,我們就要了解 JavaScript,身為一門「標準化程式語言」的身份
要怎麼判斷一門程式語言有沒有標準化
一種方式,就是上網搜尋,你有沒有辦法去「下載」到他
有些語言,像是 Python 或 Java
你可以明確地找到某個載點
像是 Download Python 或 Install Java
但是像 C, C++, JavaScript
你卻不會看到有載點叫做「把 JavaScript 安裝進你的主機」
原因是,像是 Python, Java 這兩門語言
都有背後的核心開發團隊,他們會負責寫編譯器、直譯器
而這些團隊可能是大公司或是某些社群
而一門語言的走向,幾乎完全被這個核心團隊所主導
但是有些語言,因為他們一開始的特性可能就是「要廣為使用」
他們會使用另一種方式,「只設計程式的語法」
一般來說,我們指的 Java, Python
除了像是他們的 public
static
void
class
in
這些語法
我們還會把他的執行環境也包含進去
像是我們所說的「安裝 Java」或是「寫 Java」
其實是下載 JVM 這個引擎(執行環境後)
把你使用 Java 語法的文字檔丟進去給他執行
但是像是跟 JavaScript 相近的標準化語言
他們當初在設計時,只會推出所謂的「規範」(你可以把它想成規格書、是很抽象的東西)
舉例來說,JavaScript 所使用的規範(規格書)叫做 ECMAScript
我們常聽到的 「ES6」,就是在 2015 年推出的 ECMAScript 第六版
其中,這些規格書的內容都會寫的很抽象
舉例來說,像是 ES6 其中一段內容可能接近這樣
在 ECMAScript 定完後,他們該做什麼呢?
答案是:「ECMA 他們什麼都不幹」
原因是,為了讓 JavaScript 能夠廣為流傳
他們會特別只規定 JavaScript 該有哪些特性,或是關鍵字
至於寫出一套可以「執行 JavaScript」語法的引擎(執行環境)
就交由世界上的各個開發者來開發了了!
runtime
、實作只要有人寫出一種新的 JavaScript 執行環境
我們就可以說,「他是 JavaScript 的一種實作」
你應該常常聽到一個名詞,叫做 runtime
就是這裡實作、執行環境的意思!
瀏覽器端
在瀏覽器端,各家公司都有發展自己的 JavaScript Runtime(參考資料)
舉例來說,像是 Google 的 V8,就是專門用來給 Chrome 使用的 JavaScript 引擎
他的底層是使用 C++ 寫的
而像是 SpiderMonkey, JavaScriptCore, Chakra
分別是由 Mozilla、蘋果、微軟為他們自己的 Firefox, Safari, Edge 所開發的瀏覽器實作
伺服器端
當然,早在 Node.js 之前,其實就有其他 Project 去實作 JavaScript 了!
像是 Rhino, Nashorn,就是使用 JVM 這個執行環境去跑你的 JavaScript
而我們今天的主角,Node.js
是當初有個開發者 Ryan Dahl
他那時候想要寫一個當時覺得很酷炫的功能 - 「上傳進度條」
(因為那時候連 ajax 才剛開始有)
他發現現有的 Ruby, PHP,本身開發非同步的伺服器行為表現都很糟糕
早期的 Ruby, PHP,他們幾乎沒有任何的並行
他們就算開不同的執行緒,在接收一個請求後
都會卡著直到回傳結束,非常的沒有效率
那時候他想解決這些並行的方式
就是使用 JavaScript 初期就有的 Event Loop 和 單線程的的特性
來看是否可行
Ryan Dahl 在 2009 年的 JSConf EU 展示了使用 C/C++ 來各種伺服器功能
像是 HTTP,以及 fs(讀寫檔案) 的函式庫
並成功 Demo 了使用 Node 寫的一個 IRC 伺服器
之後 Node 有了許多生態系,包含我們後續要介紹的 NPM 和 CommonJS
藉由介紹「規範」,希望可以讓大家更了解不同程式語言的設計
像是 C/C++ 同時也有像是 C99, C++2017 這樣的規格
他們一樣是只發表抽象的規範
而保留不同編譯器開發團隊很大的自由去決定該怎麼實作
(這也是有個名詞「undefined behavior」要命的地方,像是 C 因為他接近電腦底層,一點不確定的地方都最好不要有,可是有些寫法卻沒有完全定義在規格書裡「應該編譯出來長怎樣」,踩到這樣的雷通常很痛苦)
Node.js 基本上只是使用了 Google V8 引擎,並且補足了關於網路、檔案系統的函式庫
所開發出的另一套 JavaScript 實作
在明天,我們將會介紹現在發展最活躍的套件管理器「NPM」
他不只提供了一種可管理的方式來處理你的各種依賴(Dependency)
他的安裝方式、package.json、使用的模組化方式
深深影響了整個 JavaScript 生態系,甚至是其他苦於套件管理的程式語言
我們明天見!
最近用JS練習寫後端,看到這篇有種撥雲見日的感覺,
一開始前端在 import,後端在 require,都搞不清楚在做什麼了XD。
是說這篇提到了 bebel 是要解決標準化但不通用的問題,
那跟 browserify 的關係又是什麼呢?
我稍微研究了一下,
babel 是幫我把新語法轉譯成舊語法或瀏覽器看得懂的語法,
browserify 是可以讓我使用 require 語法來增添不同模組化標準的模組,
請問我這樣理解有錯誤嗎?
那這樣這邊的提到 babel 介紹是不是改為 browserfiy 比較適合呢?
(是下一篇才有提到 babel,留錯篇了)
一些意見:
...
舉例來說,像是 ES6 其中一段內容可能接近這樣JavaScript 應該新增 const ,他是一個關鍵字
只要他被賦過值,就不應該再被改變
「賦值」其實是一個發源自中國的糟糕翻譯,原文是assign,因此使用「指派」會更精準。
早期的 Ruby, PHP,他們幾乎沒有任何的並行
他們就算開不同的執行緒,在接收一個請求後
都會卡著直到回傳結束,非常的沒有效率
那時候他想解決這些並行的方式
就是使用 JavaScript 初期就有的 Event Loop 和 單線程的的特性
來看是否可行
雖然正確的將concurrent稱為「並行」很值得掌聲,但一下「執行緒」一下「線程」的錯亂還是容易造成讀者困惑。
以上意見供您參考